#ifndef SYSTEM_H
#define SYSTEM_H

#include <QObject>
#include <QDir>
#include <QCoreApplication>
#include <QDateTime>
#include <QStringList>
#include <QNetworkInterface>
#include <QDebug>
#include <QSettings>
#include <QTimer>
#include <stdio.h>
#include <QSysInfo>

#ifdef _TTY_POSIX_
#include <sys/sysinfo.h>
#include <sys/vfs.h>
#include <sys/utsname.h>
#endif


#include "DataType/NetParam.h"
#include "File/Ini/LocalIni.h"
#include "DataType/DataType.h"
#include "execinfo.h"
#include "csignal"
#include "signal.h"
#include "mi_sys.h"
#include "mi_common_datatype.h"
#include "Device/BaseDevice.h"

class System : public QObject
{
    Q_OBJECT
public:

    static System* getInstance()
    {
        if(!m_pInstance)
        {
            QMutexLocker lock(&m_Mutex);
            if(!m_pInstance)
            {
                System *pInstance = new System();
                m_pInstance = pInstance;
            }
        }
        return m_pInstance;
    }

    static void handlerr(int signum)
      {
              QString filePath="/root/home/err";
              QDir dir(filePath);
              if(!dir.exists())
              {
                  dir.mkpath(filePath);
              }
              QString strCurDay = QDate::currentDate().toString("yyyy_MM_dd");
              QString fileName = QString("%1/Error_Log_").arg(filePath) + strCurDay + QString(".txt");

              QFile file(fileName);
              bool isOPen = file.open(QIODevice::Append | QIODevice::WriteOnly);
              QTextStream text_stream(&file);

              if(!isOPen)
              {
                  exit(0);
              }

              QDateTime dateTime = QDateTime::currentDateTime().toLocalTime();
              text_stream << "################################################"<<"\r\n";
              text_stream << QString("[crash signal number:%1]").arg(signum)<<"\r\n";

              const int len=1024;
              void *func[len];
              size_t size;
              int i;
              char **funs;

              signal(signum,SIG_DFL);
              size = backtrace(func,len);
              funs = (char**)backtrace_symbols(func,size);
              fprintf(stderr,"System error,Stack trace:\n");
              for(i=0;i<size;i++)
              {
                  fprintf(stderr,"%d,%s \n",i,funs[i]);
                  QString strCmdLine = "./addr2line -C -f -e TestQtGui %1 -s";

                  std::string symbol(funs[i]);
                  size_t pos1 = symbol.find_first_of("[");
                  size_t pos2 = symbol.find_last_of("]");
                  std::string address = symbol.substr(pos1+1,pos2-pos1-1);
                  QString strAddress = QString::fromStdString(address);

                  qDebug()<<QString("[crash signal address: %1]").arg(strAddress);
                  text_stream << QString("[crash signal address:%1]").arg(strAddress)<<"\r\n";

        /*          QString strCMD = QString(strCmdLine).arg(strAddress);
                  system(strCMD.toStdString().c_str());
    */

                  /*FILE *fPipe = popen(strCMD.toStdString().c_str(),"r");
                  if(fPipe != NULL)
                  {
                      char buff[1024];
                      memset(buff,0,sizeof(buff));
                      char *ret = fgets(buff,sizeof(buff),fPipe);
                      while(ret != NULL)
                      {
                          qDebug()<<"write data = "<<(ret);
                          text_stream << QString("data %1").arg(ret) << "\r\n";
                          ret = fgets(buff,sizeof(buff),fPipe);
                      }
                      pclose(fPipe);
                  }*/

              }

              free(funs);
              file.flush();
              file.close();
              exit(1);

           //   qDebug()<<QString("[crash signal number: %1]").arg(signum);
           //   exit(signum);

      }

    QString appFilePath();
    QString appDirPath();
    QString rootPath();

    QByteArray timeBCD();
    void setTimeBCD(const QByteArray &timeBCD);

    NetParam netParam();
    bool setNetParam(const NetParam &netParam);
    bool setTempNetParam(quint8  ipMode);

    quint32 totalRamSize();
    quint32 usedRamSize();
    quint64 totalFlashSize();
    quint64 usedFlashSize();
    QString runningTime();
    void rebootSystem();
    QString appVersion();
    QString systemName();
    QString systemVersion();
    quint8 deviceType();
    void readVersion();
        void enableRS485();
     quint32 getKNXMac();
     void setKNXMac(quint32 mac);



     quint8 getKNXStatus();
     void setKNXStatus(quint8 status);

     void setGlobalStatus(quint8 status);
    quint8 getGlobalStatus();

    QString ReadUuid();


    static QString ip();

    QMap<QString,QMetaObject> getDeviceMetaMap();
    void setDeviceMetaMap(QMap<QString,QMetaObject> deviceMetaMap);

    QMap<QString,BaseDevice*> getDeviceInstanceMap();
    void setDeviceInstanceMap(QMap<QString,BaseDevice*> deviceInstanceMap);

private:
    explicit System(QObject *parent = 0);
    ~System();
    System(const System &);
    System &operator=(const System &);

    static System* m_pInstance;
    static QMutex m_Mutex;

    QTimer *detectIPTimer;
    QTimer *watchdogTimer;
    QTimer *checkLogFileTimer;
    QString m_Version;
    bool m_watchdogIOState;
    quint64 m_second;
    int fd;
    quint32 m_KNXMac;
    quint8 m_kNXStatus;
    quint8 m_globalStatus;
    QMap<QString,QMetaObject> m_deviceMetaMap;
    QMap<QString,BaseDevice*> m_deviceInstanceMap;


signals:
    void detectedIpSignal();
private slots:
    void timeoutSlot();
    void watchdogSlot();
    void checkLogFileSlot();
};

#endif // SYSTEM_H
